/* * Copyright (c) 2003 The Nutch Organization. All rights reserved. Use subject * to the conditions in http://www.nutch.org/LICENSE.txt. */ package net.nutch.plugin; import java.io.File; import java.io.IOException; import java.net.MalformedURLException; import java.net.URL; import java.util.ArrayList; import java.util.HashMap; import java.util.Locale; import java.util.MissingResourceException; import java.util.ResourceBundle; import java.util.logging.Logger; import net.nutch.util.LogFormatter; /** * The <code>PluginDescriptor</code> provide access to all meta information of * a nutch-plugin, as well to the internationalizable resources and the plugin * own classloader. There are meta information about <code>Plugin</code>, * <code>ExtensionPoint</code> and <code>Extension</code>. To provide * access to the meta data of a plugin via a descriptor allow a lazy loading * mechanism. * * @author joa23 */ public class PluginDescriptor { private String fPluginPath; private String fPluginClass; private String fPluginId; private String fVersion; private String fName; private String fProviderName; private HashMap fMessages = new HashMap(); private ArrayList fExtensionPoints = new ArrayList(); private ArrayList fDependencies = new ArrayList(); private ArrayList fExportedLibs = new ArrayList(); private ArrayList fNotExportedLibs = new ArrayList(); private ArrayList fExtensions = new ArrayList(); private PluginClassLoader fClassLoader; public static final Logger LOG = LogFormatter .getLogger(PluginDescriptor.class.getName()); /** * Constructor * * @param pId * @param pVersion * @param pName * @param pProviderName * @param pPluginclazz * @param pPath */ public PluginDescriptor(String pId, String pVersion, String pName, String pProviderName, String pPluginclazz, String pPath) { setPath(pPath); setPluginId(pId); setVersion(pVersion); setName(pName); setProvidername(pProviderName); setPluginClass(pPluginclazz); } /** * @param pPath */ private void setPath(String pPath) { fPluginPath = pPath; } /** * Returns the name of the plugin. * * @return String */ public String getName() { return fName; } /** * @param providerName */ private void setProvidername(String providerName) { fProviderName = providerName; } /** * @param name */ private void setName(String name) { fName = name; } /** * @param version */ private void setVersion(String version) { fVersion = version; } /** * Returns the fully qualified name of the class which implements the * abstarct <code>Plugin</code> class. * * @return the name of this plug-in's runtime class or <code>null</code>. */ public String getPluginClass() { return fPluginClass; } /** * Returns the unique identifier of the plug-in or <code>null</code>. * * @return String */ public String getPluginId() { return fPluginId; } /** * Returns an array of extensions. * * @return Exception[] */ public Extension[] getExtensions() { return (Extension[]) fExtensions.toArray(new Extension[fExtensions .size()]); } /** * Adds a extension. * * @param pException */ public void addExtension(Extension pExtension) { fExtensions.add(pExtension); } /** * Sets the pluginClass. * * @param pluginClass * The pluginClass to set */ private void setPluginClass(String pluginClass) { fPluginClass = pluginClass; } /** * Sets the plugin Id. * * @param pluginId * The pluginId to set */ private void setPluginId(String pluginId) { fPluginId = pluginId; } /** * Adds a extension point. * * @param extensionPoint */ public void addExtensionPoint(ExtensionPoint extensionPoint) { fExtensionPoints.add(extensionPoint); } /** * Returns a array of extension points. * * @return ExtensionPoint[] */ public ExtensionPoint[] getExtenstionPoints() { return (ExtensionPoint[]) fExtensionPoints .toArray(new ExtensionPoint[fExtensionPoints.size()]); } /** * Returns a array of plugin ids. * * @return String[] */ public String[] getDependencies() { return (String[]) fDependencies .toArray(new String[fDependencies.size()]); } /** * Adds a dependency * * @param pId * id of the dependent plugin */ public void addDependency(String pId) { fDependencies.add(pId); } /** * Adds a exported library with a relative path to the plugin directory. * * @param libName */ public void addExportedLibRelative(String pLibPath) throws MalformedURLException { URL url = new File(getPluginPath() + File.separator + pLibPath).toURL(); fExportedLibs.add(url); } /** * Returns the directory path of the plugin. * * @return String */ public String getPluginPath() { return fPluginPath; } /** * Returns a array exported librareis as URLs * * @return URL[] */ public URL[] getExportedLibUrls() { return (URL[]) fExportedLibs.toArray(new URL[0]); } /** * Adds a not exported library with a plugin directory relativ path. * * @param pLibPath */ public void addNotExportedLibRelative(String pLibPath) throws MalformedURLException { URL url = new File(getPluginPath() + File.separator + pLibPath).toURL(); fNotExportedLibs.add(url); } /** * Returns a array of libraries as URLs that are not exported by the plugin. * * @return URL[] */ public URL[] getNotExportedLibUrls() { return (URL[]) fNotExportedLibs .toArray(new URL[fNotExportedLibs.size()]); } /** * Returns a cached classloader for a plugin. Until classloader creation all * needed libraries are collected. A classloader use as first the plugins * own libraries and add then all exported libraries of dependend plugins. * * @return PluginClassLoader the classloader for the plugin */ public PluginClassLoader getClassLoader() { if (fClassLoader != null) return fClassLoader; ArrayList arrayList = new ArrayList(); arrayList.addAll(fExportedLibs); arrayList.addAll(fNotExportedLibs); arrayList.addAll(getDependencyLibs()); File file = new File(getPluginPath()); File[] files = file.listFiles(); try { for (int i = 0; i < files.length; i++) { File file2 = files[i]; String path = file2.getAbsolutePath(); if (file2.getAbsolutePath().endsWith("properties")) arrayList.add(file2.getParentFile().toURL()); } } catch (MalformedURLException e) { LOG.fine(getPluginId() + " " + e.toString()); } URL[] urls = (URL[]) arrayList.toArray(new URL[arrayList.size()]); fClassLoader = new PluginClassLoader(urls, PluginDescriptor.class .getClassLoader()); return fClassLoader; } /** * @return Collection */ private ArrayList getDependencyLibs() { ArrayList list = new ArrayList(); collectLibs(list, this); return list; } /** * @param list */ private void collectLibs(ArrayList pLibs, PluginDescriptor pDescriptor) { String[] pPluginIds = pDescriptor.getDependencies(); for (int i = 0; i < pPluginIds.length; i++) { String id = pPluginIds[i]; PluginDescriptor descriptor = PluginRepository.getInstance() .getPluginDescriptor(id); URL[] libs = descriptor.getExportedLibUrls(); for (int j = 0; j < libs.length; j++) { URL url = libs[j]; pLibs.add(url); } collectLibs(pLibs, descriptor); } } /** * Returns a internationalizabel resource string. The resource bundles could * be stored in root directory of a plugin in the well know i18n file name * conventions. * * @param pKey * @param pLocale * @return String * @throws IOException */ public String getResourceString(String pKey, Locale pLocale) throws IOException { if (fMessages.containsKey(pLocale.toString())) { ResourceBundle bundle = (ResourceBundle) fMessages.get(pLocale .toString()); try { return bundle.getString(pKey); } catch (MissingResourceException e) { return '!' + pKey + '!'; } } try { ResourceBundle res = ResourceBundle.getBundle("messages", pLocale, getClassLoader()); return res.getString(pKey); } catch (MissingResourceException x) { return '!' + pKey + '!'; } } }